package cn.botter.auth.domain.service.impl;

import cn.botter.auth.common.enums.IsDeletedEnum;
import cn.botter.auth.common.enums.UserStatusEnum;
import cn.botter.auth.domain.contants.AuthConstant;
import cn.botter.auth.domain.convert.AuthUserConvert;
import cn.botter.auth.domain.entity.AuthUserBO;
import cn.botter.auth.domain.redis.RedisUtil;
import cn.botter.auth.domain.service.AuthUserDomainService;
import cn.botter.auth.infra.basic.entity.*;
import cn.botter.auth.infra.basic.service.*;
import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @BelongsProject: bo-club
 * @BelongsPackage: service.impl
 * @Author: 爱写Bug的Botter
 * @CreateTime: 2025-03-16:02:14
 * @Description: 描述
 * @Version: 1.0
 */
@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class AuthUserDomainServiceImpl implements AuthUserDomainService {
    @Resource
    private AuthUserService authUserService;
    @Resource
    private AuthRoleService authRoleService;
    @Resource
    private AuthUserRoleService authUserRoleService;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private AuthRolePermissionService authRolePermissionService;
    @Resource
    private AuthPermissionService authPermissionService;
    private String authPermissionPrefix = "auth.permission";
    private String authRolePrefix = "auth.role";
    private static String salt = SaSecureUtil.sha256("botter");
    private String LOGIN_PREFIX = "loginCode";
    @Override
    public Integer register(AuthUserBO authUserBO) {
        AuthUser authUser = AuthUserConvert.INSTANCE.convertBoToAuthUser(authUserBO);
        // 用户是否存在
        long response = authUserService.queryUser(authUser);
        if (response == 0) {
            authUser.setIsDeleted(IsDeletedEnum.UN_DELETED.getCode());
            authUser.setStatus(UserStatusEnum.OPEN.getCode());
            authUser.setAvatar("https://tse2-mm.cn.bing.net/th/id/OIP-C.C6ohk-HyIUXiNeqNeKurlAHaHa?rs=1&pid=ImgDetMain.jpg");
            /*新增用户时，将用户角色初始化成普通角色*/
            AuthRole authRole = new AuthRole();
            authRole.setRoleKey(AuthConstant.NORMAL_USER);
            AuthRole authRoleResult =  authRoleService.queryContains(authRole);
            if (authUser.getPassword()!=null) {
                authUser.setPassword(SaSecureUtil.md5BySalt(authUser.getPassword(),salt));  /*对用户密码进行加密*/
            }
            Integer insert = authUserService.insert(authUser);
            AuthUserRole authUserRole = new AuthUserRole();
            authUserRole.setUserId(authUser.getId());
            authUserRole.setRoleId(authRoleResult.getId());
            authUserRole.setIsDeleted(IsDeletedEnum.UN_DELETED.getCode());
            authUserRoleService.insert(authUserRole);
            /*将信息存入到redis缓存中*/
            //将role相关的东西放入redis中
            String roleKey = redisUtil.buildKey(authRolePrefix, authUser.getUserName());
            List<AuthRole> roleList = new LinkedList<>();
            roleList.add(authRoleResult);
            redisUtil.set(roleKey , new Gson().toJson(roleList));
            //再将permission的东西放入redis中
            AuthRolePermission authRolePermission = new AuthRolePermission();
            authRolePermission.setRoleId(authRoleResult.getId()); //通过roleID查询所有的permission
            List<AuthRolePermission> authRolePermissionList = authRolePermissionService.queryByConditions(authRolePermission);
            List<Integer> permissionIdList = authRolePermissionList.stream().
                    map(AuthRolePermission::getPermissionId).collect(Collectors.toList());
            List<AuthPermission> authPermissionList = authPermissionService.queryByConditions(permissionIdList);
            String permissionKey = redisUtil.buildKey(authPermissionPrefix, authUser.getUserName());
            redisUtil.set(permissionKey , new Gson().toJson(authPermissionList));
            return insert ;
        }
        else{
            return 0;
        }
    }

    @Override
    public Boolean update(AuthUserBO authUserBO) {
        AuthUser authUser = AuthUserConvert.INSTANCE.convertBoToAuthUser(authUserBO);
        return authUserService.update(authUser)>0;
    }

    @Override
    public Boolean delete(AuthUserBO authUserBO) {
        AuthUser authUser = AuthUserConvert.INSTANCE.convertBoToAuthUser(authUserBO);
        authUser.setIsDeleted(IsDeletedEnum.DELETED.getCode());
        return authUserService.update(authUser) > 0;
    }

    @Override
    public AuthUserBO getUserInfo(AuthUserBO authUserBO) {
        AuthUser authUser = AuthUserConvert.INSTANCE.convertBoToAuthUser(authUserBO);
        AuthUser response = authUserService.queryByUserName(authUser);
        AuthUserBO responseBO = AuthUserConvert.INSTANCE.convertAuthUserToBO(response);
        return responseBO;
    }

    @Override
    public SaTokenInfo doLogin(String validCode) {
        String buildKey = redisUtil.buildKey(LOGIN_PREFIX, validCode);
        String openid = redisUtil.get(buildKey);
        if (openid == null) {
            return null;
        }
        AuthUserBO authUserBO = new AuthUserBO();
        authUserBO.setUserName(openid);

        Integer register = this.register(authUserBO);
        StpUtil.login(openid);
        return StpUtil.getTokenInfo();
    }
}
